#ifndef _LSCOROUTIN_H
#define _LSCOROUTIN_H

#include <setjmp.h>

#define PLATFORM_X86_VC 

#ifdef PLATFORM_X86_VC
#include <windows.h>
#define SAVE_SP(p)  _asm mov p,ebp
#define RESTORE_SP(p) _asm mov ebp,p 
#define os_task_init(argv) _asm{mov margcaddr,ebp}   margcaddr +=8; msp=mpcurtcb->stktop; _asm{mov ebp,msp}  argv=(void *)(*((int *)margcaddr))
#define os_sys_tick() GetTickCount()
#endif
  
#define MAX_TASK_NUM 5
#define IDLE_TASK_STACK_SIZE 32
#define LOG_I printf
 
#define os_waifor(cond) \
do{\
setjmp(mpcurtcb->env);\
mpcurtcb->benvinit = 1;\
if(!(cond)){\
	mpcurtcb = mpcurtcb->next;\
	if(mpcurtcb->benvinit != 0){\
		longjmp(mpcurtcb->env,1);\
	}\
	else{\
		mpcurtcb->taskentry(mpcurtcb->arg);\
	}\
}\
}while(0)

#define os_msleep(tms) \
do{\
	mpcurtcb->tick_snap = os_sys_tick() + tms;\
	setjmp(mpcurtcb->env);\
	mpcurtcb->benvinit = 1;\
	if(!(os_sys_tick() >= mpcurtcb->tick_snap)){\
		mpcurtcb = mpcurtcb->next;\
		if(mpcurtcb->benvinit != 0){\
			longjmp(mpcurtcb->env,1);\
		}\
		else{\
			mpcurtcb->taskentry(mpcurtcb->arg);\
		}\
	}\
}while(0)

enum{
	STA_INIT = 0,
	STA_ACTIVE,//活动中
	STA_PREAVTIVE,//活动前状态（进入待运行FIFO中）
	STA_READY,//已经就绪，轮到她就可以进入active状态了
	STA_PENDING//挂起
};



typedef unsigned char uint8_t;
typedef unsigned int uint32_t;

typedef struct _tcb_t{
	int stktop;//任务栈顶指针
	//int tasksta;
	int benvinit;//跳转标签是否被正确置位
	int tick_snap;//系统tick的快照
	jmp_buf env;//跳转标签
	void (*taskentry)(void* taskname);
	void* arg;
	_tcb_t* next;
}tcb_t;

extern tcb_t* mpcurtcb;
extern int msp;
extern int mstktop;
extern int margcaddr;
extern "C"{
int os_createtask(char* taskname , void (*task)(void* taskname), void* arg , int stacksize );
int os_runtasks(void);
void os_init(int heaptopaddr);
}

#endif